using System;
using Agile.Genie.Descriptors;
using GeneratorCustomization;

namespace Descriptors.GeneratorCustomization
{
    /// <summary>
    /// Container for all columns that are special DateTime fields that are used for auditing.
    /// This means that these columns will NOT be required for appropriate stored procedures and
    /// will default their value to the database value in those stored procs.
    /// </summary>
    public class AuditDateColumn : SpecialColumn
    {
        private readonly AuditColumnAction _action;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="database">Name of the database the table is in.</param>
        /// <param name="table">Name of the table the column is in.</param>
        /// <param name="column">Name of the column.</param>
        /// <param name="action">The action (INSERT or UPDATE) that the columns value should default to the servers GetDate() value for.</param>
        /// <remarks>Only the Column name is mandatory. If the table name is not supplied then the 
        /// audit should apply for ALL tables. Same is true for the database, if it is not
        /// supplied then the audit will apply for all tables in all databases.</remarks>
        private AuditDateColumn(string database, string table, string column, AuditColumnAction action)
            : base(database, table, column)
        {
            _action = action;
        }

        /// <summary>
        /// Gets the action (INSERT or UPDATE) that the columns value should default to the servers GetDate() value for.
        /// </summary>
        public AuditColumnAction Action
        {
            get { return _action; }
        }

        /// <summary>
        /// Instantiate a new excluded table column with all required fields.
        /// </summary>
        /// <param name="database">Name of the database the table is in.</param>
        /// <param name="table">Name of the table the column is in.</param>
        /// <param name="column">Name of the column.</param>
        /// <param name="action">The action (INSERT or UPDATE) that the columns value should default to the servers GetDate() value for.</param>
        /// <returns></returns>
        public static AuditDateColumn Instantiate(string database, string table, string column, string action)
        {
            if (action.ToUpper() != "INSERT" && action.ToUpper() != "UPDATE")
                throw new ArgumentException("Action must be either INSERT or UPDATE but was: " + action);

            AuditColumnAction __action = AuditColumnAction.INSERT;
            if (action.ToUpper() == "UPDATE")
                __action = AuditColumnAction.UPDATE;

            return new AuditDateColumn(database, table, column, __action);
        }

        #region Nested type: Testing

        /// <summary>
        /// Support methods for testing use only
        /// </summary>
        public class Testing
        {
            /// <summary>
            /// Get the test excluded column. Details are:-
            /// TestDatabase; TestTable; TestColumn
            /// </summary>
            /// <returns></returns>
            public static AuditDateColumn GetTestColumn()
            {
                return Instantiate("TestDatabase", "TestTable", "TestColumn", "INSERT");
            }
        }

        #endregion
    }
}